package advertising.handler

import advertising.AppParams
import ch.hsr.geohash.GeoHash
import org.apache.http.client.HttpClient
import org.apache.http.client.methods.HttpGet
import org.apache.http.util.EntityUtils

//  .--,       .--,
// ( (  \.---./  ) )
//  '.__/o   o\__.'
//     {=  ^  =}
//      >  -  <
//     /       \
//    //       \\
//   //|   .   |\\
//   "'\       /'"_.-~^`'-.
//      \  _  /--'         `
//    ___)( )(___
//   (((__) (__)))    高山仰止, 景行行止; 虽不能至, 心向往之.
//                    High mountains, scenery. Although not to, the heart yearns for it. 
object LBSHandler {

  private def lbsHasExists(geoHash: String) = {
    val connection = DBHandler.getConnection()
    val sql = "select business from geo where geoHash = ?"
    val statement = connection.prepareStatement(sql)
    statement.setString(1, geoHash)
    val resultSet = statement.executeQuery()
    val exists = resultSet.next()
    connection.close()
    exists
  }

  private def updateLBS(geoHash: String, business: String) = {
    val connection = DBHandler.getConnection()
    val sql = "update geo set business = ? where geoHash = ?"
    val statement = connection.prepareStatement(sql)
    statement.setString(1, business)
    statement.setString(2, geoHash)
    statement.executeUpdate()
    connection.close()
  }

  private def insertLBS(geoHash: String, business: String) = {
    val connection = DBHandler.getConnection()
    val sql = "insert into geo(geoHash, business) values(?, ?)"
    val statement = connection.prepareStatement(sql)
    statement.setString(1, geoHash)
    statement.setString(2, business)
    statement.executeUpdate()
    connection.close()
  }

  /**
    * 将商圈信息保存到数据库，构建商圈知识库
    * @param geoHash
    * @param business
    */
  def save2DB(geoHash: String, business: String) = {
    val exists = lbsHasExists(geoHash)
    if(exists) {
      updateLBS(geoHash, business)
    } else {
      insertLBS(geoHash, business)
    }
  }

  /**
    * 获取百度请求 URL
    * @param longitude
    * @param latitude
    * @return 请求 URL
    */
  def getUrl(longitude:Double, latitude:Double) = {
    "http://api.map.baidu.com/geocoder/v2/?callback=renderReverse&location=" +
      longitude +
      "," +
      latitude +
      "&output=json&pois=1&ak=" +
      AppParams.ak
  }

  def getBusiness(responseBody:String) = {
    JsonHandler.parserLBSJson(responseBody).getJSONObject("result").getString("business")
  }

  def getResponseBody(httpClient: HttpClient, url: String) = {
    // GET 方式
    val get = new HttpGet(url)
    val response = httpClient.execute(get)
    // 获取状态码
    val statusCode = response.getStatusLine.getStatusCode
    val responseBody = EntityUtils.toString(response.getEntity)
    (statusCode, responseBody)
  }

  /**
    * 获取八位 GeoHash
    * @param latitude
    * @param longitude
    * @return 八位 GeoHash
    */
  def getGeoHash(latitude:Double, longitude:Double) = {
    GeoHash.geoHashStringWithCharacterPrecision(latitude, longitude, 8)
  }

  /**
    * 通过 web api 从百度获取商圈
    * @param latitude
    * @param longitude
    * @param httpClient
    * @return 商圈信息
    */
  def getBusinessFromBaidu(latitude:Double, longitude:Double, httpClient:HttpClient) = {
    val url = getUrl(latitude, longitude)
    val response = getResponseBody(httpClient, url)
    val statusCode = response._1
    val responseBody = response._2
    if(statusCode == 200){
      getBusiness(responseBody)
    } else {
      null
    }
  }

  /**
    * 从知识库中获取商圈信息
    * @param latitude
    * @param longitude
    * @return 商圈信息
    */
  def getBusinessFromDB(latitude:Double, longitude:Double) = {
    val geoHash = getGeoHash(latitude, longitude)
    val connection = DBHandler.getConnection()
    val sql = "select business from geo where geoHash = ?"
    val statement = connection.prepareStatement(sql)
    statement.setString(1, geoHash)
    val resultSet = statement.executeQuery()
    if(resultSet.next()) {
      resultSet.getString(1)
    } else {
      null
    }
  }

}
